#include "plc_proc.h"

const uint16  WAIT_CTS_TIME = 300;
const byte  LOCAL_ADDRESS = 1;

PlcSendMsgState  plc_send_state = 0;
byte xdata plc_send_mode = 0x11;
byte xdata waiting_cts_counter = 0;

const byte xdata request_to_send[] = {0x68, 2, 0x68, 0x05, 0x16 };
const byte xdata clear_to_send[] = {0x68, 2, 0x68, 0x06, 0x16 };
const byte xdata hello_world_msg[] = {0x68, 2, 0x68, 0x07, 0x11,0x12,0x13, 0x16 };


byte xdata msg_to_send[256];
byte xdata msg_to_send_length = 0;
byte carrier_senser = 0;

byte xdata msg_recevied[256];

struct{
	byte address;
	enum MsgType type;
	byte received_data[256];
	byte length;
}msg_received;

bool add_carrier_senser()
{
	if(carrier_senser < 200)
	{
		++carrier_senser;
	}
	return true;
}

bool clear_carrier_senser()
{
	carrier_senser = 0;
	return true;
}
			 

bool decode_plc_received_msg(unsigned char * pHead, byte length)
{
	byte i = 0;	
	for(i = 0; i< length ; i++)
	{
		msg_recevied[i]=pHead[i];
	}		  
	
	msg_received.address = pHead[1];
	msg_received.type = pHead[3];

	for(i = 0; i< length-4 ; i++)
	{
		msg_received.received_data[i]=pHead[i+4];
	}		
	msg_received.length = length - 3;

	if(msg_received.address != LOCAL_ADDRESS)
	{
		msg_received.length = 0;		
		if(msg_received.type == BEAT)
		{
			printf("decode_plc_received_msg: received BEAT from Node %bx. \n",msg_received.address);		
		}
		else if(msg_received.type == BROARDCAST)
		{
			printf("decode_plc_received_msg: received BROARDCAST from Node %bx. \n",msg_received.address);		
		}
		else
		{
			printf("decode_plc_received_msg: not this address msg. \n");
		}
	}
	else
	{
		printf("decode_plc_received_msg: Set plc received msg. msg type: 0x%2bx. \n",msg_received.type);		
	}

	return true;
}

bool plc_receive_msg_proc()
{
	if(msg_received.length > 0)
	{
		switch(msg_received.type)
		{
		case BROARDCAST:
			printf("plc_receive_msg_proc: received BEAT from Node %bx. \n",msg_received.address);		
			break;
		case BEAT:
			printf("plc_receive_msg_proc: received BROARDCAST from Node %bx. \n",msg_received.address);			
			break;
		case RequestToSend:
			printf("plc_receive_msg_proc: recevied RTS, send CTS.\n");
			PlcSend(clear_to_send,sizeof(clear_to_send),plc_send_mode);
			break;
		case ClearToSend:
			/*
			if(plc_send_state==Plc_Waiting_CTS)
			{
				plc_send_state = Plc_Send_Msg;
				printf("plc_receive_msg_proc: recevied CTS.\n");			
			}
			*/			
			return true;

		default:
			printf("plc_receive_msg_proc: recevied unknown message.\n");				
			break;
		}
		msg_received.length = 0;
	}
	return true;
}



bool next_send_mode()
{
	switch(plc_send_mode)
	{
	case 0x10:
		plc_send_mode = 0x11;
		break;
	case 0x11:
		plc_send_mode = 0x12;
		break;
	case 0x12:
		plc_send_mode = 0x22;
		break;
	case 0x22:
		plc_send_mode = 0x42;
		break;
	case 0x42:
		plc_send_mode = 0x82;
	case 0x82:
		plc_send_mode = 0xFF;
		break;		
	}
	return true;
}



byte get_plc_send_mode()
{	
	return plc_send_mode;
}


bool plc_send_rts()
{
	PLCSend(request_to_send,sizeof(request_to_send),plc_send_mode);	
	return true;
}

bool plc_waiting_cts()
{
	if(msg_received.length == 0)
	{
		waiting_cts_counter++;
		return false;
	}

	printf("plc_waiting_cts: received msg type %bu \n",msg_received.type);
	if(msg_received.type == ClearToSend)
	{
		waiting_cts_counter = 0;
		return true;
		printf("plc_waiting_cts: received msg CTS \n");
	}

	waiting_cts_counter++;
	return false; 	
}
